package com.chenjt.netty.eight_nio.bufferAttribute;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;

/**
 * 注释：关于buffer的Scattering与Gathering
 * 测试 telnet 127.0.0.1 8899
 * 之后输入内容，输入的内容超过9个字符，cmd上就会回显输入的内容
 *
 * @author chenjt
 * @date 2024/8/22 10:28
 */
public class BufferScatterAndGather {

    public static void main(String[] args) throws Exception {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        InetSocketAddress address = new InetSocketAddress(8899);
        serverSocketChannel.socket().bind(address);

        int messageLength = 2 + 3 + 4;

        ByteBuffer[] buffers = new ByteBuffer[3];

        buffers[0] = ByteBuffer.allocate(2);
        buffers[1] = ByteBuffer.allocate(3);
        buffers[2] = ByteBuffer.allocate(4);

        SocketChannel socketChannel = serverSocketChannel.accept();

        while (true) {
            int bytesRead = 0;

            while (bytesRead < messageLength) {
                // 往三个ByteBuffer里面写数据，cmd窗口关闭时，读取不到内容这里会一直返回-1
                long r = socketChannel.read(buffers);
                bytesRead += r;

                System.out.println("bytesRead:" + bytesRead);

                // 数据写入之后，将三个ByteBuffer的position和limit的值都打印出来
                Arrays.asList(buffers).stream()
                        .map(buffer -> "position:" + buffer.position() +
                                ",limit:" + buffer.limit())
                        .forEach(System.out::println);

            }

            Arrays.asList(buffers).forEach(buffer -> {
                buffer.flip();
            });

            long bytesWritten = 0;
            while(bytesWritten < messageLength){
                // 将所有数据都写回客户端
                long r = socketChannel.write(buffers);
                bytesWritten += r;
            }

            Arrays.asList(buffers).forEach(buffer -> {
                buffer.clear();
            });

            System.out.println("bytesRead:" + bytesRead + ",bytesWritten:" + bytesWritten
            + ",messageLength:" + messageLength);


        }


    }

}
